package com.baizw.cultivation.module.flowable.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baizw.cultivation.common.exception.GlobalException;
import com.baizw.cultivation.module.flowable.entity.ModelEntity;
import com.baizw.cultivation.module.flowable.mapper.ModelMapper;
import com.baizw.cultivation.module.flowable.service.IModelService;
import com.baizw.cultivation.module.flowable.util.FlowableUtil;
import com.baizw.cultivation.util.ShiroUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.DeploymentBuilder;
import org.flowable.ui.modeler.domain.Model;
import org.flowable.ui.modeler.serviceapi.ModelService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.io.Serializable;

import static com.baizw.cultivation.module.flowable.consts.FlowableConsts.ACCEPT_FILE_TYPE;

/**
 * Flowable模型ServiceImpl
 *
 * @author 剧终1204
 * @version V1.0
 * @date 2020年12月01日 15:36
 */
@Slf4j
@Service
@AllArgsConstructor
public class IModelServiceImpl extends ServiceImpl<ModelMapper, ModelEntity> implements IModelService {
	
	private final ModelService modelService;
	private final RepositoryService repositoryService;
	
	@Override
	public boolean saveOrUpdate(ModelEntity entity) {
		return super.saveOrUpdate(entity);
	}
	
	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean removeById(Serializable id) {
		try {
			modelService.deleteModel(String.valueOf(id));
		} catch (Exception exception) {
			log.error("模型删除失败", exception);
			throw new GlobalException("模型删除失败");
		}
		return true;
	}
	
	@Override
	public boolean deploy(String modelId) {
		try {
			Model model = modelService.getModel(modelId);
			// 到时候需要添加分类
			String categoryCode = "1000";
			BpmnModel bpmnModel = modelService.getBpmnModel(model);
			// 添加隔离信息
			String tenantId = "flow";
			// 必须指定文件后缀名否则部署不成功
			DeploymentBuilder deployment = repositoryService.createDeployment();
			deployment.name(model.getName());
			deployment.key(model.getKey());
			deployment.category(categoryCode);
			deployment.tenantId(tenantId);
			deployment.addBpmnModel(model.getKey() + ".bpmn", bpmnModel);
			deployment.deploy();
			return true;
		} catch (Exception e) {
			log.error("部署流程异常: ", e);
			return false;
		}
	}
	
	@Override
	public boolean importModel(MultipartFile file) {
		String fileName = file.getOriginalFilename();
		if (file.isEmpty() || StrUtil.isBlank(fileName)) {
			throw new GlobalException("无效的上传文件");
		}
		if (!StrUtil.endWithAny(fileName, ACCEPT_FILE_TYPE)) {
			throw new GlobalException("仅支持 .bpmn和.bpmn20.xml文件，文件" + fileName + "不在支持范围内");
		}
		try {
			InputStream inputStream = file.getInputStream();
			Model model = FlowableUtil.verifyAndBuilder(inputStream, ShiroUtil.getUser().getLoginName());
			modelService.createModel(model, FlowableUtil.buildRemoteUser());
			return true;
		} catch (Exception e) {
			log.error("模型导入失败", e);
			return false;
		}
	}
	
}
